#!/usr/bin/perl -wT
# -*- Mode: perl; indent-tabs-mode: nil -*-
#
# The contents of this file are subject to the Mozilla Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is the Bugzilla Bug Tracking System.
# 
# The Initial Developer of the Original Code is Netscape Communications
# Corporation. Portions created by Netscape are Copyright (C) 1998
# Netscape Communications Corporation. All Rights Reserved.
# 
# Contributor(s): TomWij <TomWij@live.com>

##############################################################################
#
# trainClassifier.cgi
# ---------------------
# Train a model using the classifier on bugs from a specific component.
#
##############################################################################

use DBI;
use DBD::mysql;

print "Content-type: text/html\n\n";

# Get the severity map.
require severityMap;
our %toClassifier;
our %fromClassifier;

# Get the POST parameters.
do 'helpers\query.cgi';

# Get all the bugs from the MySQL table 'bugs'.
do '..\..\..\localconfig';
$driver = DBI->install_driver("mysql"); 
$connect = $driver->connect("DBI:mysql:database=$db_name;host=$db_host", $db_user, $db_pass, {}) or print "<b>MySQL: Connection failed.</b>";

$query = "SELECT b.bug_severity, b.short_desc, bf.comments FROM bugs b JOIN bugs_fulltext bf ON b.bug_id = bf.bug_id WHERE b.product_id = " . $FORM{pid} . " AND b.component_id = " . $FORM{cid};
$query_handle = $connect->prepare($query) or print "<b>MySQL: Query Preparation failed.</b>";

$query_handle->execute() or print "<b>MySQL: Query Execution failed.</b>";

$query_handle->bind_columns(undef, \$severity, \$summary, \$content);

# Form an identifier so model names are unique.
$id = $db_name . '-' . $FORM{pid} . '-' . $FORM{cid};

# Get classifier.
open (MYFILE, 'data/classifier');
$classifier = <MYFILE>;
close(MYFILE);

# Get classification.
open (MYFILE, "data/classification");
$classification = <MYFILE>;
close(MYFILE);

# Allow execution by de-tainting everything.
$ENV{'PATH'} =~ /(.*)/; $ENV{'PATH'} = $1;
$id =~ /(.*)/; $id = $1;
$classifier =~ /(.*)/; $classifier = $1;

# Form an arff file in string format from the bugs.
open (MYFILE, '>', "data/$id-string.arff");
# Form a sorted list of classes.
$classes = "";
foreach $key (sort(keys %fromClassifier))
{
	$classes = $classes . $key . ',';
}
chop($classes);
# Print the header of the arff file.
print MYFILE "\@relation data\n\n\@attribute short_desc string\n\@attribute bug_severity {$classes}\n\n\@data\n";

# Ensure that there is a bug so that the model gets made, as this string is most likely to never be used it won't have any influence.
@values = values %toClassifier;
$randomSeverity = $values[0];
print MYFILE "'BugPrediction1337',$randomSeverity\n";

# Fetch all the bugs and save those to the file for which the severity has been mapped.
while($query_handle->fetch()) {
	if (exists $toClassifier{$severity})
	{
		$description = "";

		if ($classification eq "title")
		{
			$description = $summary;
		}
		elsif ($classification eq "content")
		{
			$description = $content;
		}
		elsif ($classification eq "both")
		{
			$description = $summary . " " . $content;
		}
		$description =~ s/[^\w\s-]//g;
		
		# Strip all non-alphanumeric characters.
		$severity = $toClassifier{$severity};

		print MYFILE "'$description',$severity\n";
	}
}
close (MYFILE);

# Turn the string format arff file into a vector format arff file.
`java -Xmx1024M -cp weka.jar weka.filters.unsupervised.attribute.StringToWordVector -S -C -R 1 -M 1 -L -c 2 -i data/$id-string.arff -o data/$id-vector.arff`;

# Initially train the model using the vector format arff file.
`java -Xmx1024M -cp weka.jar $classifier -t data/$id-vector.arff -d data/$id-model.arff`;

# Let the user know that we are done training.
print '<h3>Train Bug Prediction</h3><p><b>Done!</b></p>';